using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using AppTableUtils;
using System.Data;


/// <summary>
/// 古希腊掌管创建图片的神
/// </summary>
public class CreateImg : MonoBehaviour
{
    // 点击按钮, 增加一个slot
    public GameObject slot_prefab;
    // public slot slot_prefab;
    public GameObject slotGrid;

    public string bag_fname = "背包物品.csv";
    string bag_fpath
    {
        get
        {
            return BdUtils.join(BdUtils.persistant_data_dir_path, bag_fname);
        }
    }

    public string item_fname = "物品清单.xlsx";
    string item_fpath
    {
        get
        {
            return BdUtils.join(BdUtils.data_table_dir_path, item_fname);
        }
    }

    DataTable _bag_dt;
    public DataTable bag_dt
    {
        get
        {
            if (_bag_dt == null)
            {
                if (!File.Exists(bag_fpath))
                {
                    BdUtils.copy_file_from_streaming_to_persistant(bag_fname);
                }

                BdUtils.assert(File.Exists(bag_fpath), $"`bag_fpath[{bag_fpath}]`不存在?");
                _bag_dt = TableUtils.read_csv_data_on_all_platform(file_name: bag_fname, primary_key: "ID", priority_persistent_data: true);
            }
            return _bag_dt;
        }
    }
    DataTable _item_dt;
    public DataTable item_dt
    {
        get
        {
            if (_item_dt == null)
            {
                _item_dt = TableUtils.read_table(item_fname, primary_key: "ID");
            }
            return _item_dt;
        }
    }
    // public DataTable item_dt;


    GameObject item_description_obj;  // bag下方的描述文本
    public Text item_description_comp;  // bag下方的描述文本

    public int current_slot_index;  // 当前选中的slot

    public GameObject guard_slot;  // 交换slot的哨兵
    public Vector3 original_guard_slot_position;

    Dictionary<string, GameObject> prefab_obj_dc = new Dictionary<string, GameObject>();

    [Header("按钮_使用")]
    public Button use_button;

    [Header("按钮_丢弃")]
    public Button drop_button;
    void Start()
    {
    }

    private void OnEnable()
    {
        current_slot_index = -1;
        item_description_comp.text = "";
    }

    /// <summary>
    /// 使用当前选中`slot`中的物品`item`
    /// </summary>
    public void btn_use_item_in_current_slot()
    {
        if (current_slot_index == -1)
            return;

        var row_i = get_bag_row_i(current_slot_index);
        if (row_i == null)
            return;

        int remain_count = BdUtils.conv_to_int(row_i["数量"], 0);
        if (remain_count <= 0)
        {
            bag_dt.Rows.Remove(row_i);
            item_description_comp.text = "";
            return;
        }

        int sprite_i = get_sprite_i_by_bag_row_i(row_i);

        if (sprite_i == -1)
        {
            string msg = "目前必须有`sprite_i`的slot才能使用!";
            BdTools.show_message_box(content: msg);
            BdUtils.raise_exception_error_func(msg);
        }

        var item_info_row = get_item_info_by_bag_row_i(row_i);

        string img_path = BdUtils.conv_to_string(item_info_row["图片"]);


        int level = BdUtils.conv_to_int(item_info_row["等级"], -1);
        int type = BdUtils.conv_to_int(item_info_row["类型"], -1);

        if (level != -1 && type != -1)
        {
            BdUtils.log("--- 被点击物品信息 --- row_i:", TableUtils.conv_row_to_dc(row_i));
            // BtnCreateSoldier.instance.instantiate_soldier_obj(tag: "soldier_1", type: type, level: level);
        }
        else if (img_path.Contains("/skill_icons"))
        {
            BdUtils.log("--- 当前选中物品的信息 --- 释放技能 --- type:", type, ", level:", level, ", remain_count:", remain_count, ", img_path:", img_path);
            // SkillManager.instance.release_skill(skill_id: sprite_i + 1, player_id: 1, is_cost_money: false);
        }

        remain_count -= 1;
        row_i["数量"] = remain_count;

        if (remain_count <= 0)
        {
            bag_dt.Rows.Remove(row_i);
            item_description_comp.text = "";
        }

        // bag_dt.AcceptChanges();

        refresh_slot_grid();
        save_bag_dt();
    }

    void Awake()
    {
        current_slot_index = -1;

        TableUtils.show_data_table(item_dt);

        if (guard_slot == null)
            guard_slot = transform.Find("guard_slot").gameObject;
        BdUtils.assert(guard_slot, "`guard_slot`不能为空!");
        original_guard_slot_position = guard_slot.transform.position;
        guard_slot.GetComponent<CanvasGroup>().blocksRaycasts = false;
        
        var bag_obj = gameObject.GetComponentInParent<BagEnable>().gameObject;
        item_description_obj = BdTools.get_game_object_by_path("bottom/item_description", bag_obj);

        if (item_description_obj)
            item_description_comp = item_description_obj.GetComponent<Text>();
        refresh_slot_grid();
    }
    public string get_discription_text_by_slot_index(int slot_index)
    {
        var row_i = get_bag_row_i(slot_index);
        if (row_i == null)
            return "";
        var dc_i = TableUtils.conv_row_to_dc(row_i);
        int item_id = BdUtils.conv_to_int(dc_i["物品ID"]);

        var item_row = TableUtils.get(item_dt, pk: item_id);
        var item_info = TableUtils.conv_row_to_dc(item_row);

        string item_description = item_info["介绍"].ToString();
        return item_description;
    }

    public void clear_slot_grid()
    {

        var instance = this;
        for (int i = 0; i < instance.slotGrid.transform.childCount; i++)
        {
            if (instance.slotGrid.transform.childCount == 0)
                break;
            Destroy(instance.slotGrid.transform.GetChild(i).gameObject);
        }
    }

    public int bag_capacity = 6 * 3;

    public Sprite load_sprite(string img_dir_path, string img_file_name, bool is_prefab = false, int sprite_i = -1)
    {
        Sprite sprite = null;
        string relative_file_path;

        string FileName = Path.GetFileNameWithoutExtension(img_file_name);
        if (img_file_name.StartsWith("/"))
        {
            // BdUtils.log(" === img_file_name:", img_file_name);
            relative_file_path = img_file_name.Substring(1, img_file_name.Length - 1);
        }
        else
            relative_file_path = Path.Combine(img_dir_path, FileName);

        if (!is_prefab)
        {
            Texture2D Picture;
            if (sprite_i == -1)
            {
                Picture = Resources.Load<Texture2D>(relative_file_path);
            }
            else
            {
                Sprite[] sprite_ls = Resources.LoadAll<Sprite>(relative_file_path);
                BdUtils.assert(sprite_ls.Length > 0, $"`sprite_ls`长度为0? 路径`relative_file_path`: `{relative_file_path}`, img_dir_path:`{img_dir_path}`, `FileName`:`{FileName}`");
                BdUtils.assert(sprite_i < sprite_ls.Length, $"Error: `sprite_i[{sprite_i}]`必须小于`sprite_ls.Length[{sprite_ls.Length}]`!");
                return sprite_ls[sprite_i];
            }
            BdUtils.assert(!BdUtils.is_null(Picture), "picture不能为空");

            Rect Size = new Rect(0, 0, Picture.width, Picture.height);
            // Rect Size = new Rect(0, 0, 500, 1000);
            Vector2 Pivot = new Vector2(0, 0);
            sprite = Sprite.Create(Picture, Size, Pivot);
        }
        else
        {
            GameObject obj_i;
            if (!prefab_obj_dc.ContainsKey(relative_file_path))
            {
                obj_i = Resources.Load<GameObject>(relative_file_path);
                BdUtils.assert(obj_i != null, $"obj_i为空? relative_file_path: [{relative_file_path}]");
                Instantiate(obj_i, new Vector3(900, 450, 0), Quaternion.identity);
                // Instantiate(obj_i);
                prefab_obj_dc.Add(relative_file_path, obj_i);
            }
            else
            {
                obj_i = prefab_obj_dc[relative_file_path];
            }

            // new_item_obj = Instantiate(slot_prefab, slotGrid.transform.position, Quaternion.identity);
            SpriteRenderer sprite_renderer = obj_i.GetComponent<SpriteRenderer>();
            sprite = sprite_renderer.sprite;
        }
        return sprite;
    }

    int test_i = 0;
    public void btn_test_load_sprite()
    {
        string img_dir_path = "images/icons/";
        string img_file_name = "icons";
        bool is_prefab = false;
        int sprite_i = test_i;

        var new_item__img = transform.Find("/Canvas/img_test_load_sprite").GetComponent<Image>();
        var x = load_sprite(img_dir_path, img_file_name, is_prefab, sprite_i);
        new_item__img.sprite = x;

        test_i += 1;
    }
    string prefab_dir_path = BdUtils.join("inventory", "prefabs");
    string items_dir_path = BdUtils.join("inventory", "items");

    // 保存当前的背包信息
    public void save_bag_dt()
    {
        // --- 新存档
        // string new_path = Path.Combine(Path.GetDirectoryName(bag_dt.TableName), Path.GetFileNameWithoutExtension(bag_dt.TableName) + "_1" + Path.GetExtension(bag_dt.TableName));
        // BdUtils.log(" --- new_path: ", new_path);
        // TableUtils.save_to(bag_dt, new_path);
        StartCoroutine(_save_bag_dt());
        // Loom.QueueOnMainThread((param) =>
        // {
        //     _save_bag_dt();
        // }, null);
    }

    public IEnumerator _save_bag_dt()
    {
        // --- 保存存档
        // BdUtils.log(" --- 保存存档 --- bag_dt.TableName: ", bag_dt.TableName);
        TableUtils.save_to_csv(bag_dt, bag_dt.TableName);
        yield return null;
    }

    public void set_one_slot(GameObject new_item_obj, string img_file_name = "", int item_number = 0, bool is_prefab = false, string slot_name = "", int slot_index = -1, DataRow row_i = null)
    {
        // BdUtils.log($"new_item_obj --- {new_item_obj.name} -> {slot_name}");
        new_item_obj.name = slot_name != "" ? slot_name : $"slot_{img_file_name}";
        // new_item_obj.name = slot_name;

        // --- 设置数量
        GameObject new_item__text = new_item_obj.transform.Find("number").gameObject;  // TMP_Text
        Text text_component = new_item__text.GetComponent<Text>();

        // --- 设置slot图片
        Image new_item__img = new_item_obj.GetComponent<Image>();
        // BdUtils.log(" --- row_i:", TableUtils.conv_row_to_dc(row_i));

        if (item_number != 0)
        {
            text_component.text = $"{item_number}";

            if (img_file_name != "")
            {
                string img_dir_path = is_prefab ? prefab_dir_path : items_dir_path;
                int sprite_i = get_sprite_i_by_bag_row_i(row_i);

                // BdUtils.log("~~  lihua_obj__sprite : img_file_name", img_file_name);
                Sprite lihua_obj__sprite = load_sprite(img_dir_path, img_file_name, is_prefab: is_prefab, sprite_i: sprite_i);
                new_item__img.sprite = lihua_obj__sprite;

                new_item__img.color = new Color32(255, 255, 255, 255);
            }
        }
        else
        {
            text_component.text = "";
            new_item__img.color = new Color32(255, 255, 255, 0);
        }

        // --- 设置位置
        if (slot_index == -1)
            new_item_obj.gameObject.transform.SetParent(slotGrid.transform, false);

        var drag_slot_comp = new_item_obj.GetComponent<drag_slot>();
        // BdUtils.log(new_item_obj.name, " --- drag_slot_comp:", drag_slot_comp);
        drag_slot_comp.create_image_comp = GetComponent<CreateImg>();
        drag_slot_comp.bag_obj = GetComponentInParent<DragBag>().gameObject;
        // BdUtils.log("prent --- ", new_item_obj.gameObject.transform.parent);
    }

    public void set_one_slot(string img_file_name = "", int item_number = 0, bool is_prefab = false, string slot_name = "", int slot_index = -1, DataRow row_i = null)
    {

        GameObject new_item_obj;
        if (slot_index == -1)
        {
            // --- 初始化
            new_item_obj = Instantiate(slot_prefab, slotGrid.transform.position, Quaternion.identity);
        }
        else
        {
            BdUtils.assert(slot_index < bag_capacity, $" *** slot_index[{slot_index}]取值错误! bag的最大容量为[{bag_capacity}]!");

            try
            {
                new_item_obj = slotGrid.transform.GetChild(slot_index).gameObject;
            }
            catch (DataException e)
            {
                throw new UnityException($" *** slot_index[{slot_index}]取值错误! e:{e}");
            }

        }
        set_one_slot(new_item_obj, img_file_name, item_number, is_prefab, slot_name, slot_index, row_i);
    }

    public void swap_slot(int slot_index_1, int slot_index_2)
    {
        BdUtils.assert(slot_index_1 < bag_capacity, $" *** slot_index_1[{slot_index_1}]取值错误! bag的最大容量为[{bag_capacity}]!");
        BdUtils.assert(slot_index_2 < bag_capacity, $" *** slot_index_2[{slot_index_2}]取值错误! bag的最大容量为[{bag_capacity}]!");

        GameObject slot_obj_1 = slotGrid.transform.GetChild(slot_index_1).gameObject;
        GameObject slot_obj_2 = slotGrid.transform.GetChild(slot_index_2).gameObject;

        var row_1 = get_bag_row_i(slot_index_1);

        BdUtils.assert(row_1 != null, $" *** row_1[{row_1}]不能为`null`!");


        var row_2 = get_bag_row_i(slot_index_2);

        string img_file_name;
        int item_number;
        bool is_prefab;
        (img_file_name, item_number, is_prefab) = get_slot_info_by_row_i(row_1);

        row_1["格子位置"] = slot_index_2;

        if (row_2 != null)
            row_2["格子位置"] = slot_index_1;

        refresh_slot_grid();

        save_bag_dt();
    }

    public DataRow get_item_info_by_bag_row_i(DataRow row_i)
    {
        var dc_i = TableUtils.conv_row_to_dc(row_i);
        string key = "物品ID";
        var keys = BdUtils.conv_obj_to_json(dc_i.Keys);
        BdUtils.assert(dc_i.ContainsKey(key), $"dc_i未包含key[{key}]! dc_i.Keys: {keys}");
        int item_id = BdUtils.conv_to_int(dc_i[key]);

        var item_row = TableUtils.get(item_dt, pk: item_id);
        return item_row;
    }

    public int get_sprite_i_by_bag_row_i(DataRow row_i)
    {
        if (row_i == null)
            return -1;
        var item_row = get_item_info_by_bag_row_i(row_i);
        int sprite_i = BdUtils.conv_to_int(item_row["sprite_i"].ToString(), -1);
        return sprite_i;
    }

    public (string, int, bool) get_slot_info_by_row_i(DataRow row_i)
    {
        var dc_i = TableUtils.conv_row_to_dc(row_i);
        var item_row = get_item_info_by_bag_row_i(row_i);

        var item_info = TableUtils.conv_row_to_dc(item_row);

        // 获取`img_file_name`
        string img_file_name = item_info["图片"].ToString();
        int item_number = (int)BdUtils.conv_to_int(dc_i["数量"]);

        var _is_prefab = item_info["预制体"];
        bool is_prefab = BdUtils.conv_to_bool(_is_prefab);

        img_file_name = is_prefab ? _is_prefab.ToString() : img_file_name;

        return (img_file_name, item_number, is_prefab);
    }

    public DataRow get_bag_row_i(int slot_index)
    {
        var row_i = TableUtils.get(bag_dt, select: $"格子位置 = '{slot_index}'");
        return row_i;
    }
    public void refresh_slot_grid()
    {
        if (!gameObject.activeInHierarchy)
            return;
        
        clear_slot_grid();

        for (var i = 0; i < bag_capacity; i++)
        {
            refresh_one_slot_grid(i);
        }
    }

    // 由于slot_grid的数据结构问题, 这里不能单独使用...
    void refresh_one_slot_grid(int i, DataRow row_i = null)
    {
        if (row_i == null)
            row_i = get_bag_row_i(i);

        if (row_i == null)
        {
            set_one_slot(slot_name: $"empty_{i}");
        }
        else
        {
            string slot_name = $"slot_{i}";
            var (img_file_name, item_number, is_prefab) = get_slot_info_by_row_i(row_i);
            set_one_slot(img_file_name, item_number, is_prefab, slot_name: slot_name, row_i: row_i);
        }
    }
}
